package cn.com.sparkle.paxos;

import java.util.concurrent.locks.ReentrantLock;

import org.apache.log4j.Logger;

import cn.com.sparkle.paxos.iomodel.protobuffmessage.PaxosMessages.ElectionId;
import cn.com.sparkle.paxos.iomodel.protobuffmessage.PaxosMessages.Id;
import cn.com.sparkle.paxos.util.IdComparator;

//import cn.com.sparkle.paxos.model.ElectionId;

public class SelfState {
	private final static Logger logger = Logger.getLogger(SelfState.class);
	private volatile ElectionId.Builder electionVoteIdBySelf;
	private volatile ElectionId.Builder electionPrepareId;
	private ReentrantLock electionPrepareIdLock = new ReentrantLock();

	public ElectionId.Builder getElectionVoteIdBySelf() {
		return electionVoteIdBySelf;
	}

	public SelfState(Configuration conf) {
		electionVoteIdBySelf = ElectionId.newBuilder()
				.setId(Id.newBuilder().setIncreaseId(0).setAddress(""))
				.setVersion(conf.getVersion());
		// new ElectionId(0, "", conf.getVersion());
		electionPrepareId = ElectionId.newBuilder()
				.setId(Id.newBuilder().setIncreaseId(-1).setAddress(""))
				.setVersion(conf.getVersion());
		// new ElectionId(-1, "", conf.getVersion());
	}

	public ElectionId casElectionPrepareId(ElectionId id) {
		try {
			electionPrepareIdLock.lock();
			int compareResult = IdComparator.getInstance().compare(id.getId(),
					electionPrepareId.getId());

			if (compareResult != 0) {
				logger.debug(id.getId().getIncreaseId()
						+ id.getId().getAddress()
						+ (compareResult == 1 ? ">" : "<")
						+ electionPrepareId.getId().getIncreaseId()
						+ electionPrepareId.getId().getAddress());
			}
			if (compareResult >= 0
			// if (id.compareTo(electionPrepareId) >= 0
					&& electionPrepareId.getVersion() == id.getVersion()) {
				electionPrepareId = ElectionId.newBuilder().mergeFrom(id);
				return id;
			}
			return electionPrepareId.build();
		} finally {
			electionPrepareIdLock.unlock();
		}
	}
	// public volatile long electionPrepareInstanceId;

}
